package com.campus.academic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.campus.academic.job.entity.Grades;
import com.campus.academic.job.vo.StuGradesVO;
import com.campus.academic.job.vo.StudentsGradesVO;
import com.campus.academic.mapper.GradesMapper;
import com.campus.academic.service.IGradesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.api.util.UserContext;
import com.campus.common.exception.ServiceException;
import com.campus.common.result.Result;
import com.campus.common.student.job.entity.Student;
import com.campus.common.student.mapper.StudentMapper;
import com.campus.common.teacher.job.entity.Teacher;
import com.campus.common.teacher.mapper.TeacherMapper;
import com.campus.common.user.entity.pojo.User;
import com.campus.common.user.mapper.AuthMapper;
import com.campus.course.dto.entity.CourseRecords;
import com.campus.course.dto.entity.Courses;
import com.campus.course.mapper.CourseRecordsMapper;
import com.campus.course.mapper.CoursesMapper;
import com.campus.course.service.ICourseRecordsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 成绩表 服务实现类
 * </p>
 *
 * @author mwb
 * @since 2024-11-16
 */
@Service
public class GradesServiceImpl extends ServiceImpl<GradesMapper, Grades> implements IGradesService {

    @Autowired
    private GradesMapper gradesMapper;

    @Autowired
    private AuthMapper authMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private CoursesMapper coursesMapper;

    @Autowired
    private CourseRecordsMapper courseRecordsMapper;

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private ICourseRecordsService iCourseRecordsService;



    /**
     * 查看某门考试的学生成绩
     */
    @Override
    public List<StudentsGradesVO> getGrade(Integer courseId) {
        int userId = UserContext.getUserId();
        Teacher teacher = teacherMapper.selectOne(new LambdaQueryWrapper<Teacher>()
                .eq(Teacher::getUserId, userId));
        if (Optional.ofNullable(teacher).isEmpty()) {
            throw new ServiceException("未查询到该用户信息");
        }

        List<Grades> gradesList = gradesMapper.selectList(new LambdaQueryWrapper<Grades>()
                .eq(Grades::getTeacherId, teacher.getId())
                .eq(Grades::getCourseId, courseId));

        // 获取所有需要查询的学生 ID
        Set<Integer> studentIds = gradesList.stream().map(Grades::getStudentId).collect(Collectors.toSet());
        // 查询所有需要的学生信息并缓存
        Map<Integer, Student> studentMap = studentMapper.selectList(new LambdaQueryWrapper<Student>()
                        .in(Student::getId, studentIds))
                .stream()
                .collect(Collectors.toMap(Student::getId, student -> student));

        // 获取所有需要查询的用户 ID
        Set<Integer> userIds = studentMap.values().stream()
                .map(Student::getUserId)
                .collect(Collectors.toSet());

        // 查询所有需要的用户信息并缓存
        Map<Integer, User> userMap = authMapper.selectList(new LambdaQueryWrapper<User>()
                        .in(User::getId, userIds))
                .stream()
                .collect(Collectors.toMap(User::getId, user -> user));

        List<StudentsGradesVO> list = new ArrayList<>();
        for (Grades grades : gradesList) {
            Student student = studentMap.get(grades.getStudentId());
            if (Optional.ofNullable(student).isEmpty()) {
                throw new ServiceException("未查询到该学生信息");
            }

            User user = userMap.get(student.getUserId());
            if (Optional.ofNullable(user).isEmpty()) {
                throw new ServiceException("未查询到该用户信息");
            }

            StudentsGradesVO studentsGradesVO = new StudentsGradesVO();
            studentsGradesVO.setId(grades.getId());
            studentsGradesVO.setStudentId(grades.getStudentId());
            studentsGradesVO.setName(user.getName());
            studentsGradesVO.setSex(user.getSex());
            studentsGradesVO.setExamScore(grades.getExamScore());
            studentsGradesVO.setUsualScore(grades.getUsualScore());
            //计算最终成绩
            if (grades.getUsualScore() != null) {
                studentsGradesVO.setEndScore(grades.getExamScore().multiply(BigDecimal.valueOf(0.5))
                        .add(grades.getUsualScore().multiply(BigDecimal.valueOf(0.5))));
                studentsGradesVO.setRanks(grades.getRanks());
            }
            list.add(studentsGradesVO);
        }
        return list;
    }


    /**
     * 录入学生成绩
     */
    @Override
    public List<StudentsGradesVO> inputGrades(Integer courseId, List<BigDecimal> examScores, List<BigDecimal> usualScores) {
        int userId = UserContext.getUserId();
        Teacher teacher = teacherMapper.selectOne(new LambdaQueryWrapper<Teacher>()
                .eq(Teacher::getUserId, userId));
        if (Optional.ofNullable(teacher).isEmpty()) {
            throw new ServiceException("未查询到该用户信息");
        }
        //获取该课程的学生名单
        List<CourseRecords> courseRecordsList = courseRecordsMapper.selectList(new LambdaQueryWrapper<CourseRecords>()
                .eq(CourseRecords::getCourseId, courseId));

        if (usualScores.size() != courseRecordsList.size() || examScores.size() != courseRecordsList.size()) {
            throw new ServiceException("上传失败，请检查数据是否合理填满");
        }

        List<StudentsGradesVO> list = new ArrayList<>();
        Map<Integer, Map<BigDecimal, BigDecimal>> map = new HashMap<>();
        for (int i = 0; i < courseRecordsList.size(); i++) {
            CourseRecords courseRecords = courseRecordsList.get(i);
            Map<BigDecimal, BigDecimal> bigMap = new HashMap<>();
            BigDecimal examScore = examScores.get(i);
            BigDecimal usualScore = usualScores.get(i);
            bigMap.put(examScore, usualScore);
            map.put(courseRecords.getStudentId(), bigMap);
        }

        map.forEach((studentId,scoreMap) -> {
            Grades grades = gradesMapper.selectOne(new LambdaQueryWrapper<Grades>()
                    .eq(Grades::getCourseId, courseId)
                    .eq(Grades::getStudentId, studentId)
                    .eq(Grades::getTeacherId, teacher.getId()));
            Student student = studentMapper.selectById(studentId);
            User user = authMapper.selectById(student.getUserId());
            Courses courses = coursesMapper.selectById(courseId);
            if (grades != null) {
                StudentsGradesVO vo = new StudentsGradesVO();
                vo.setId(grades.getId());
                vo.setStudentId(studentId);
                vo.setExamScore(scoreMap.keySet().iterator().next()); // 获取考试成绩
                vo.setUsualScore(scoreMap.values().iterator().next()); // 获取平时成绩
                BigDecimal end = scoreMap.keySet().iterator().next().multiply(BigDecimal.valueOf(0.5))
                        .add(scoreMap.values().iterator().next().multiply(BigDecimal.valueOf(0.5)))
                        .setScale(0, RoundingMode.HALF_UP);
                vo.setEndScore(end);
                vo.setName(user.getName());
                vo.setSex(user.getSex());
                vo.setCourseName(courses.getCourseName());
                vo.setCourseId(courses.getId());

                grades.setExamScore(scoreMap.keySet().iterator().next());
                grades.setUsualScore(scoreMap.values().iterator().next());
                gradesMapper.updateById(grades);
                list.add(vo);
            }
        });


        return list;
    }

    @Override
    public Result getStuGrades() {
        int userId = UserContext.getUserId();
        //获取学生学号(id)
        Student student = studentMapper.selectOne(
                new QueryWrapper<Student>().eq("user_id", userId)
        );
        //查找学生选课
        List<CourseRecords> records = courseRecordsMapper.selectList(
                new LambdaQueryWrapper<CourseRecords>().eq(CourseRecords::getStudentId,student.getId())
        );
        List<StuGradesVO> stuGradesVOS = new ArrayList<>();
        //装配成绩单信息
        for (CourseRecords record : records) {
            Courses course = coursesMapper.selectById(record.getCourseId());
            StuGradesVO stuGradesVO = new StuGradesVO();
            stuGradesVO.setCourseId(course.getId());
            stuGradesVO.setCourseName(course.getCourseName());
            Grades grade = gradesMapper.selectOne(
                    new LambdaQueryWrapper<Grades>().eq(Grades::getTeacherId,course.getTeacherId())
                            .eq(Grades::getStudentId,student.getId())
                            .eq(Grades::getCourseId,course.getId())
            );
            if (grade != null) {
                if (grade.getRanks() != null) {
                    stuGradesVO.setRanks(grade.getRanks().toString());
                }
                else {
                    stuGradesVO.setRanks("未录入");
                }
                if (grade.getUsualScore() != null) {
                    stuGradesVO.setUsualScore(grade.getUsualScore().toString());
                }
                else {
                    stuGradesVO.setUsualScore("未录入");
                }
                if (grade.getExamScore() != null) {
                    stuGradesVO.setExamScore(grade.getExamScore().toString());
                }
                else {
                    stuGradesVO.setExamScore("未录入");
                }
            }
            stuGradesVO.setRanks("未录入");
            stuGradesVO.setUsualScore("未录入");
            stuGradesVO.setExamScore("未录入");
            stuGradesVOS.add(stuGradesVO);
        }
        return Result.success(stuGradesVOS,"返回学生成绩单成功");
    }
}
